package com.ibiaoke.customer.service;

import com.ibiaoke.common.base.Page;
import com.ibiaoke.common.response.Res;
import com.ibiaoke.common.utils.AssertUtils;
import com.ibiaoke.customer.consts.PayTypeConst;
import com.ibiaoke.customer.consts.TradeTypeConsts;
import com.ibiaoke.customer.dao.DepositDao;
import com.ibiaoke.customer.entity.Customer;
import com.ibiaoke.customer.entity.Deposit;
import com.ibiaoke.customer.entity.DepositRecorder;
import com.ibiaoke.customer.entity.TradeRecorder;
import com.ibiaoke.customer.entity.vo.DepositVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Created by Administrator on 2017/6/19.
 */
@Service("depositService")
public class DepositServiceImpl implements DepositService {

    @Autowired
    private DepositDao depositDao;
    @Autowired
    private CustomerService customerService;
    @Autowired
    private TradeRecorderService tradeRecorderService;
    @Autowired
    private DepositChargeService depositChargeService;
    @Autowired
    private DepositRecorderService depositRecorderService;

    @Override
    public List<Deposit> listDeposit(String customerMobile, Page page) {
        Integer customerId = null;
        if (StringUtils.isNotBlank(customerMobile)) {
            customerId = customerService.getCustomerId(customerMobile);
        }

        List<Deposit> depositList = depositDao.listDeposit(customerId, page);
        return depositList;
    }

    @Override
    public DepositVO getDeposit(Integer customerId) {
        AssertUtils.notNull(customerId, "用户标识不能为空");

        Deposit deposit = depositDao.getDeposit(customerId);
        DepositVO depositVO = new DepositVO();
        depositVO.setDepositId(deposit.getDepositId());
        depositVO.setCustomerId(deposit.getCustomerId());
        depositVO.setPreDeposit(deposit.getPreDeposit().toString());
        depositVO.setFreezeDeposit(deposit.getFreezeDeposit());
//        BeanUtils.copyProperties(deposit, depositVO);
        return depositVO;
    }

    @Override
    public int createNewDeposit(Integer customerId) {
        Deposit deposit = new Deposit();
        deposit.setCustomerId(customerId);
        deposit.setFreezeDeposit(BigDecimal.ZERO);
        deposit.setPreDeposit(BigDecimal.ZERO);
        deposit.setErrorCount(0);
        deposit.setCreateTime(new Date());
        deposit.setUpdateTime(new Date());
        return depositDao.insertSelective(deposit);
    }

    @Override
    public Res depositCharge(Integer customerId, BigDecimal money, Integer payType, String openId, String ip) {
        AssertUtils.notNull(customerId, "用户id不能为空");
        AssertUtils.notNull(money, "充值金额不能为空");
        TradeRecorder tradeRecorder = tradeRecorderService.createTradeRecorder(customerId, payType, money, TradeTypeConsts.CHARGE);
        if (Objects.equals(PayTypeConst.WECAHT, payType)) {
            Map<String, String> payInfo = depositChargeService.chargeDepositByWeChat(tradeRecorder, openId);
            return Res.create().addResponse("payInfo", payInfo);
        } else if (Objects.equals(PayTypeConst.ALIPAY, payType)) {
            String payInfo = depositChargeService.chargeDepositByAliPay(tradeRecorder);
            return Res.create().addResponse("payInfo", payInfo);
        }
        if (Objects.equals(PayTypeConst.APP_ALIPAY, payType)) {
            String payInfo = depositChargeService.chargeDepositByAliAppPay(tradeRecorder);
            return Res.create().addResponse("payInfo", payInfo);
        }
        if (Objects.equals(PayTypeConst.APP_WECAHT, payType)) {
            Map<String, Object> payInfo = depositChargeService.chargeDepositByWeChatApp(tradeRecorder, ip);
            return Res.create().addResponse("payInfo", payInfo);
        }
        return Res.createErrorRes("不支持的充值方式");
    }

    @Override
    public int depositCharge(Integer customerId, BigDecimal monney) {
        Deposit deposit = depositDao.getDeposit(customerId);
        BigDecimal preDeposit = deposit.getPreDeposit();
        preDeposit = preDeposit.add(monney);
        deposit.setPreDeposit(preDeposit);
        deposit.setUpdateTime(new Date());
        return depositDao.updateByPrimaryKeySelective(deposit);
    }

    @Override
    public int payOrder(Integer customerId, BigDecimal orderPrice) {
        Deposit deposit = depositDao.getDeposit(customerId);
        BigDecimal preDeposit = deposit.getPreDeposit();
        AssertUtils.requireTrue(preDeposit.compareTo(orderPrice) >= 0, "余额不足");
        preDeposit = preDeposit.subtract(orderPrice);
        deposit.setPreDeposit(preDeposit);
        return depositDao.updatePreDeposit(deposit.getDepositId(), preDeposit);
    }

    @Override
    @Transactional
    public int updatePrice(Integer customerId, BigDecimal money) {
        //获得deposit表中的会员id
        Deposit deposit = depositDao.getDeposit(customerId);
        //获得deposit表中的可用预存款
        BigDecimal preDeposit = deposit.getPreDeposit();
        //preDeposit等于预存款+money
        preDeposit = preDeposit.add(money);
        //设置预存款的值
        deposit.setPreDeposit(preDeposit);
        //返回
        return depositDao.updatePreDeposit(deposit.getDepositId(), preDeposit);
    }

    @Override
    public Integer updateDeposit(String customerMobile, BigDecimal money, Integer type) {
        Customer customer = customerService.getCustomer(customerMobile);
        AssertUtils.notNull(customer, "该用户不存在");
        Deposit deposit = depositDao.getDeposit(customer.getCustomerId());
        BigDecimal preDeposit = deposit.getPreDeposit();
        if (type == 1 || type == 2) {
            preDeposit = preDeposit.add(money);
        } else if (type == 3) {
            preDeposit = preDeposit.subtract(money);
        }
        deposit.setPreDeposit(preDeposit);
        Integer Dcount = depositDao.updatePreDeposit(deposit.getDepositId(), preDeposit);
        Integer count = null;
        if (Dcount > 0) {
            DepositRecorder depositRecorder = new DepositRecorder();
            depositRecorder.setCustomerId(customer.getCustomerId());
            depositRecorder.setPayType(3);
            depositRecorder.setTransactionNo(tradeRecorderService.generateTradeNo());
            depositRecorder.setRecorderMonney(money);
            //type{1、退款 2、会员返利、3取现}
            switch (type) {
                case 1:
                    depositRecorder.setRemark("退款");
                    depositRecorder.setTradeType(3);
                    break;
                case 2:
                    depositRecorder.setRemark("会员返利");
                    depositRecorder.setTradeType(1);
                    break;
                case 3:
                    depositRecorder.setRemark("取现");
                    depositRecorder.setTradeType(3);
                    break;
                default:
                    depositRecorder.setRemark("退款");
                    depositRecorder.setTradeType(3);
                    break;
            }
            depositRecorder.setCreateTime(new Date());
            depositRecorder.setUpdateTime(new Date());
            count = depositRecorderService.insertByRefund(depositRecorder);
        }
        return count;
    }
}
